package com.cz.basetool.ui_work.util.log;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.cz.basetool.ui_work.thread.MainHandler;
import com.cz.basetool.ui_work.thread.ThreadManager;
import com.cz.basetool.ui_work.util.data.AbsQueueTaskHelper;
import com.cz.basetool.ui_work.util.file.CZFileUtil;
import com.cz.basetool.ui_work.util.safe.FileEncrypter;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by XinYi on 2019/5/15.
 * 日志的控制
 */

public class CZLocalLogPrinter {
    private Context mContext;
    private static final String TAG = "CZLocalLogPrinter";
    private boolean isDebug = true;
    private static final CZLocalLogPrinter ourInstance = new CZLocalLogPrinter();
    private Config config = getDefaultConfig();
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");


    public static CZLocalLogPrinter getInstance() {
        return ourInstance;
    }

    private CZLocalLogPrinter() {
        WriteLogQueueTaskHelper.getInstance().init();
        WriteLogQueueTaskHelper.getInstance().setOnTaskActivateListener(new AbsQueueTaskHelper.OnTaskActivateListener() {
            @Override
            public void onTaskActivate(final Object item) {
                Log.d("WriteLogQueueTaskHelper", "onTaskActivate: 执行任务---" + item);
                ThreadManager.getInstance().executeTaskWithoutException(new Runnable() {
                    @Override
                    public void run() {
                        boolean write;
                        if(config.isSafeSaveLog() == false){
                            write = CZFileUtil.write(config.getLogFileParentPath() + File.separator + config.getFileName(), config.getHead() + item);
                        }else{
                            String minWen = config.getHead() + item;
                            String encrypt = FileEncrypter.encrypt(minWen+"\n");
                            write = CZFileUtil.write(config.getLogFileParentPath() + File.separator + config.getFileName(),encrypt,false);
                        }

                        Log.d(TAG, "write: " + write);
                        MainHandler.getInstance().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                WriteLogQueueTaskHelper.getInstance().next();
                            }
                        },10);
                    }
                });
            }
        });
    }

    public void setDebug(boolean debug) {
        isDebug = debug;
    }

    /**
     * 初始化自定义
     * @param context
     * @param config        null:表示使用默认的配置
     */
    public void init(Context context,Config config){
        if(config != null){
            this.config = config;
        }
        this.mContext = context;

        //每次开机刷新一下，防止文件过大导致内存不够用。
        refreshLogFile();
    }

    public void writeLog(String log){
        Log.d(TAG, "writeLog1: " + log);
        if(isDebug == false) return;
        WriteLogQueueTaskHelper.getInstance().join(log);
    }
    public void writeLog(String tag,String log){
        Log.d(TAG, "writeLog2: " + log);
        if(isDebug == false) return;
        WriteLogQueueTaskHelper.getInstance().join(tag + ":" + log);
    }

    public StringBuilder readLog(){
        return CZFileUtil.read(config.fileName);
    }


    /**
     * 刷新日志文件
     */
    public void refreshLogFile(){
        ThreadManager.getInstance().executeTaskWithoutException(new Runnable() {
            @Override
            public void run() {
                File fileParent = new File(config.getLogFileParentPath());
                File[] files = fileParent.listFiles();

                //删除过期的日志数据
                if(config.createFileNameByDate){
                    if(files != null && files.length > 0){
                        for (File file :files){
                            Log.e(TAG,"file name = " + file.getName());
                            int index = file.getName().indexOf("ScjLog.txt");
                            String timeStr = file.getName().substring(0, index);
                            try {
                                Date date = dateFormat.parse(timeStr);
                                if(System.currentTimeMillis() - date.getTime() > config.cachedDays * 24 * 60 * 60 * 1000){
                                    file.delete();
                                    writeLog("删除过期日志文件：" + file.getAbsolutePath());
                                }
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }

                        }
                    }
                }

                //清除大文件
                files = fileParent.listFiles();
                if(files != null && files.length > 0) {
                    for (File file : files) {
                        if(file.length() > config.maxFileSize * 1024 * 1024){
                            file.delete();
                            writeLog("删除超大日志文件：" + file.getAbsolutePath());
                        }
                    }
                }

                //刷新目录及文件
                CZFileUtil.refreshDir(config.getLogFileParentPath(),mContext);
            }
        });
    }


    /**
     * 清空日志但是不删除文件
     */
    public void clearLog(){
        if(isDebug == false) return;

        //清空日志数据
        File fileParent = new File(config.getLogFileParentPath());
        File[] files = fileParent.listFiles();
        if(files != null && files.length > 0){
            for (File file :files){
                CZFileUtil.clear(file.getAbsolutePath());
            }
        }
    }

    public static class Config{
        private String fileName;                        //文件路径
        private boolean createFileNameByDate;         //通过日期创建文件名
        private String logFileParentPath;              //设置日志文件父路径
        private String fileNameDate;
        private boolean safeSaveLog;                   //是否安全存储日志，加密。
        private int cachedDays;                         //日志缓存天数
        private int maxFileSize;                         //文件大小最大多少

        public Config() {
            fileName = "ScjLog.txt";
            logFileParentPath = Environment.getExternalStorageDirectory().getAbsolutePath();
            createFileNameByDate = false;
            safeSaveLog = false;
            cachedDays = 5;
            maxFileSize = 5;


            //防止每次调用getFileName都重新获取
            Date now = new Date();
            if(dateFormat == null){
                dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            }

            fileNameDate = dateFormat.format(now) + "ScjLog.txt";
        }

        public Config setFileName(String fileName) {
            this.fileName = fileName;
            return this;
        }

        public Config setCreateFileNameByDate(boolean createFileNameByDate) {
            this.createFileNameByDate = createFileNameByDate;
            return this;
        }

        public Config setLogFileParentPath(String logFileParentPath) {
            this.logFileParentPath = logFileParentPath;
            return this;
        }

        public Config setSafeSaveLog(boolean safeSaveLog) {
            this.safeSaveLog = safeSaveLog;
            return this;
        }

        public Config setMaxFileSize(int maxFileSize) {
            this.maxFileSize = maxFileSize;
            return this;
        }

        public String getHead(){
            Date now = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss#");
            return dateFormat.format(now);
        }

        public String getFileName() {
            if(createFileNameByDate == false){
                return fileName;
            }else{
                return fileNameDate;
            }
        }

        public String getLogFileParentPath() {
            return logFileParentPath;
        }

        public boolean isSafeSaveLog() {
            return safeSaveLog;
        }
    }

    private Config getDefaultConfig(){
       return new Config().setFileName("ScjLog.txt")
               .setLogFileParentPath(Environment.getExternalStorageDirectory() + "/xjLog")
               .setSafeSaveLog(false)
               .setCreateFileNameByDate(true);
    }
}
